package com.pipayshop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pipayshop.entity.HotelShopInfo;
import com.pipayshop.entity.HotelShopRegion;
import com.pipayshop.entity.HotelUserAdmin;
import com.pipayshop.entity.HotelUserInfo;
import com.pipayshop.entity.dto.HotelLoginDTO;
import com.pipayshop.entity.dto.HotelUserAdminDTO;
import com.pipayshop.entity.vo.AccountInfoVO;
import com.pipayshop.entity.vo.ResponseResultVO;
import com.pipayshop.exception.BusinessException;
import com.pipayshop.mapper.*;
import com.pipayshop.service.HotelUserInfoService;
import com.pipayshop.utils.JwtUtil;
import com.pipayshop.utils.StringUtil;
import com.pipayshop.utils.ValidationUtil;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;

@Service
public class HotelUserInfoServiceImpl extends ServiceImpl<HotelUserInfoMapper, HotelUserInfo> implements HotelUserInfoService {
    @Resource
    private HotelUserAdminMapper hotelUserAdminMapper;
    @Resource
    private HotelAccountInfoMapper hotelAccountInfoMapper;
    @Resource
    private HotelShopInfoMapper hotelShopInfoMapper;
    @Resource
    private HotelShopRegionMapper hotelShopRegionMapper;
    // 拼接前缀
    private static final String PREFIX = "piHotel@";

    @Override
    public ResponseResultVO login(HotelLoginDTO loginDTO) {
        // 查询账户是否存在
        HotelUserAdmin hotelUserAdmin = hotelUserAdminMapper.selectOne(
                new LambdaQueryWrapper<HotelUserAdmin>()
                        .apply("BINARY pi_name = {0}", PREFIX + loginDTO.getUserName()));
        if (hotelUserAdmin == null) {
            throw new BusinessException("username_not_found");
        }
        // 存在，验证密码
        boolean b = StringUtil.checkPassword(loginDTO.getPassword(), hotelUserAdmin.getPassword());
        if (b) {
            // 生成token
            String jwt = JwtUtil.createJWT(loginDTO.getUserName());
            //把token响应给前端
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", jwt);
            map.put("username", PREFIX+loginDTO.getUserName());

            return new ResponseResultVO(200, "login_success", map);
        }
        throw new BusinessException("incorrect_account_or_password");
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)  // 保证所有异常都会回滚
    public ResponseResultVO register(HotelUserAdminDTO hotelUserAdminDTO) {
        validateHotelInfo(hotelUserAdminDTO);
        // 查询用户是否注册
        try {
            HotelUserAdmin dbHotelUserAdmin = hotelUserAdminMapper.selectOne(
                    new LambdaQueryWrapper<HotelUserAdmin>()
                            .eq(HotelUserAdmin::getPiName, PREFIX+hotelUserAdminDTO.getPiName()));
            if (dbHotelUserAdmin != null) {
                // 用户已被注册
                throw new BusinessException("username_already_registered");
            }
            // 用户未注册，执行注册逻辑
            if (hotelUserAdminDTO.getPassword().isEmpty()) {
                hotelUserAdminDTO.setPassword("123456");
            }
            // 构建注册账户实体
            String userName = PREFIX+hotelUserAdminDTO.getPiName(); // 拼接前缀，区分使用pi注册的用户具有唯一性
            String password = StringUtil.hashPassword(hotelUserAdminDTO.getPassword());
            HotelUserAdmin hotelUserAdmin = BeanUtil.copyProperties(hotelUserAdminDTO, HotelUserAdmin.class);
            hotelUserAdmin.setPassword(password);
            hotelUserAdmin.setPiName(userName);
            hotelUserAdmin.setUid(userName);
            hotelUserAdmin.setCreateTime(LocalDateTime.now());
            hotelUserAdmin.setUpdateTime(LocalDateTime.now());
            // 构建插入酒店信息实体
            HotelShopInfo hotelShopInfo = new HotelShopInfo();
            String shopId = StringUtil.generateShortId();
            hotelShopInfo.setShopId(shopId);
            hotelShopInfo.setAddress(hotelUserAdminDTO.getAddress());
            hotelShopInfo.setShopName(hotelUserAdminDTO.getShopName());
            hotelShopInfo.setUid(userName);
            hotelShopInfo.setPhone(hotelUserAdminDTO.getPhone());
            hotelShopInfo.setCategoryId(hotelUserAdminDTO.getCategoryId());
            // 构建插入酒店区域实体
            HotelShopRegion hotelShopRegion = new HotelShopRegion();
            hotelShopRegion.setRegionId(hotelUserAdminDTO.getRegionId());
            hotelShopRegion.setShopId(shopId);
            // 插入注册信息
            hotelUserAdminMapper.insert(hotelUserAdmin);
            // 插入账户信息
            hotelAccountInfoMapper.createAccount(userName);
            // 插入酒店信息
            hotelShopInfoMapper.insert(hotelShopInfo);
            // 插入酒店地区
            hotelShopRegionMapper.insert(hotelShopRegion);
        }  catch (Exception e) {
            log.error("服务器有异常: ", e);
            throw new BusinessException(e.getMessage());
        }
        return new ResponseResultVO(200, "register_success", null);
    }

    public void validateHotelInfo(HotelUserAdminDTO hotelUserAdminDTO) {
        ValidationUtil.validateString(hotelUserAdminDTO.getPiName(), "username_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getPassword(), "password_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getShopName(), "hotel_name_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getAddress(), "hotel_address_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getPhone(), "hotel_phone_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getCategoryId(), "category_required");
        ValidationUtil.validateString(hotelUserAdminDTO.getRegionId(), "region_id_required");
    }
}
